a11y: Compute the base path in the root object
authorEmmanuele Bassi <ebassi@gnome.org>
Mon, 16 Nov 2020 14:17:28 +0000 (14:17 +0000)
committerEmmanuele Bassi <ebassi@gnome.org>
Mon, 16 Nov 2020 16:44:56 +0000 (16:44 +0000)
The root path is shared by all AtSpiContext instances, so we should
compute it once, instead of every time we instantiate a new context.

This allows us to defer the path creation at realization time and ensure
that we have a registered application.

gtk/a11y/gtkatspicontext.c
gtk/a11y/gtkatspiroot.c
gtk/a11y/gtkatspirootprivate.h

index 4dad9863dd6e38c7299db18b6c67a077d3e5fcaf..735b66194500f198415c3eccf4d2f78190482d5d 100644 (file)
@@ -1458,45 +1458,6 @@ gtk_at_spi_context_constructed (GObject *gobject)
   /* Make sure that we were properly constructed */
   g_assert (self->bus_address);
 
-  /* We use the application's object path to build the path of each
-   * accessible object exposed on the accessibility bus; the path is
-   * also used to access the object cache
-   */
-  GApplication *application = g_application_get_default ();
-  char *base_path = NULL;
-
-  if (application != NULL)
-    {
-      const char *app_path = g_application_get_dbus_object_path (application);
-      base_path = g_strconcat (app_path, "/a11y", NULL);
-    }
-  else
-    {
-      char *uuid = g_uuid_string_random ();
-      base_path = g_strconcat ("/org/gtk/application/", uuid, "/a11y", NULL);
-      g_free (uuid);
-    }
-
-  /* We use a unique id to ensure that we don't have conflicting
-   * objects on the bus
-   */
-  char *uuid = g_uuid_string_random ();
-
-  self->context_path = g_strconcat (base_path, "/", uuid, NULL);
-
-  /* UUIDs use '-' as the separator, but that's not a valid character
-   * for a DBus object path
-   */
-  size_t path_len = strlen (self->context_path);
-  for (size_t i = 0; i < path_len; i++)
-    {
-      if (self->context_path[i] == '-')
-        self->context_path[i] = '_';
-    }
-
-  g_free (base_path);
-  g_free (uuid);
-
   G_OBJECT_CLASS (gtk_at_spi_context_parent_class)->constructed (gobject);
 }
 
@@ -1526,6 +1487,22 @@ gtk_at_spi_context_realize (GtkATContext *context)
       g_object_ref (self->root);
     }
 
+  /* UUIDs use '-' as the separator, but that's not a valid character
+   * for a DBus object path
+   */
+  char *uuid = g_uuid_string_random ();
+  size_t len = strlen (uuid);
+  for (size_t i = 0; i < len; i++)
+    {
+      if (uuid[i] == '-')
+        uuid[i] = '_';
+    }
+
+  self->context_path =
+    g_strconcat (gtk_at_spi_root_get_base_path (self->root), "/", uuid, NULL);
+
+  g_free (uuid);
+
   self->connection = gtk_at_spi_root_get_connection (self->root);
   if (self->connection == NULL)
     return;
@@ -1812,7 +1789,13 @@ gtk_at_spi_context_get_context_path (GtkAtSpiContext *self)
 GVariant *
 gtk_at_spi_context_to_ref (GtkAtSpiContext *self)
 {
+  g_return_val_if_fail (GTK_IS_AT_SPI_CONTEXT (self), NULL);
+
+  if (self->context_path == NULL)
+    return gtk_at_spi_null_ref ();
+
   const char *name = g_dbus_connection_get_unique_name (self->connection);
+
   return g_variant_new ("(so)", name, self->context_path);
 }
 /* }}} */
index e9a174990eed85e0c435fa643c4b9b865ea674df..583371bcec23b8ee115f47919fb98c87e2beedde 100644 (file)
@@ -51,6 +51,8 @@ struct _GtkAtSpiRoot
   char *bus_address;
   GDBusConnection *connection;
 
+  char *base_path;
+
   const char *root_path;
 
   const char *toolkit_name;
@@ -87,6 +89,7 @@ gtk_at_spi_root_finalize (GObject *gobject)
   g_clear_handle_id (&self->register_id, g_source_remove);
 
   g_free (self->bus_address);
+  g_free (self->base_path);
   g_free (self->desktop_name);
   g_free (self->desktop_path);
 
@@ -613,6 +616,27 @@ gtk_at_spi_root_constructed (GObject *gobject)
       goto out;
     }
 
+  /* We use the application's object path to build the path of each
+   * accessible object exposed on the accessibility bus; the path is
+   * also used to access the object cache
+   */
+  GApplication *application = g_application_get_default ();
+
+  if (application != NULL && g_application_get_is_registered (application))
+    {
+      const char *app_path = g_application_get_dbus_object_path (application);
+
+      self->base_path = g_strconcat (app_path, "/a11y", NULL);
+    }
+  else
+    {
+      self->base_path = g_strconcat ("/org/gtk/application/",
+                                     g_get_prgname (),
+                                     "/a11y",
+                                     NULL);
+    }
+
+
 out:
   G_OBJECT_CLASS (gtk_at_spi_root_parent_class)->constructed (gobject);
 }
@@ -687,3 +711,11 @@ gtk_at_spi_root_to_ref (GtkAtSpiRoot *self)
 
   return g_variant_new ("(so)", self->desktop_name, self->desktop_path);
 }
+
+const char *
+gtk_at_spi_root_get_base_path (GtkAtSpiRoot *self)
+{
+  g_return_val_if_fail (GTK_IS_AT_SPI_ROOT (self), NULL);
+
+  return self->base_path;
+}
index 7a99e7c25412715ca874c718733289c7c23f6638..15a6b485483d84b4f274533dfe918c7f19fa3e42 100644 (file)
@@ -42,6 +42,9 @@ gtk_at_spi_root_get_connection (GtkAtSpiRoot *self);
 GtkAtSpiCache *
 gtk_at_spi_root_get_cache (GtkAtSpiRoot *self);
 
+const char *
+gtk_at_spi_root_get_base_path (GtkAtSpiRoot *self);
+
 GVariant *
 gtk_at_spi_root_to_ref (GtkAtSpiRoot *self);